﻿Imports OMANE.Common
Imports OMANE.Common.UI
Imports OMANE.Common.Model.Interfaces
Imports System.Reflection
Imports System.IO
Imports PTIC_GestionBDD
Imports PTIC_Util
Imports Actuariat
Imports OMANE.Common.Model.Referentiel

Class App
    Inherits Global.OMANE.Common.Application

    Private Shared _instance As App
    Friend Shared ReadOnly Property Instance As App
        Get
            If _instance Is Nothing Then
                _instance = New App
            End If
            Return _instance
        End Get
    End Property

    Private serviceTypes As New List(Of Type)
    Private serviceNames As New Dictionary(Of String, Type)
    Private singleton As New Dictionary(Of Type, Object)
    Private modules As New List(Of IModule)

    Private Sub New()
        MyBase.New()
        If _instance Is Nothing Then
            _instance = Me
        End If

        create()
    End Sub

    Private Sub create()
        Dim uis As New OMANE.UIServiceImpl
        serviceNames.Add("_api_uiservice_", GetType(IUIService))
        serviceTypes.Add(GetType(IUIService))
        singleton.Add(GetType(IUIService), uis)
        uis.Initialize()

        Dim urs As New UndoRedoServiceImpl()
        serviceNames.Add("_api_undoredoservice_", GetType(IUndoRedoService))
        serviceTypes.Add(GetType(IUndoRedoService))
        singleton.Add(GetType(IUndoRedoService), urs)
        urs.Initialize()

        ''''''''''''''' Deplacer vers le module taux garantis '''''''''''''''''''''''''''''''''''
        ' L'objectif est de pouvoir accelerer le lancement de l'outil en l'absence du module taux garantis'''''''''''''
        'Dim UniversOMANE As IModelOMANE = New Model.ModelOMANE()
        'serviceNames.Add("_api_UniversService_", GetType(IModelOMANE))
        'serviceTypes.Add(GetType(IModelOMANE))
        'singleton.Add(GetType(IModelOMANE), UniversOMANE)
        'Try
        '    UniversOMANE.Initialize()
        'Catch ex As Exception
        '    IO.File.AppendAllText("log3.txt", _
        ' "[DEBUT]" & vbCrLf & _
        ' "Une erreur SAS s'est produite lors de l'initialisation de l'univers OMANE" & vbCrLf & _
        ' "[FIN]" & vbCrLf)
        'End Try
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

        ' If MySettings.Default.loadmodule Then
        'MsgBox(Directory.GetCurrentDirectory)
        Dim q = From elt In Directory.GetDirectories("Modules")
        Select Directory.GetFiles(elt, "*.dll").FirstOrDefault

        For Each elt In q
            LoadModule(elt)
        Next
        'End If



        'Dim qr = From e In AppDomain.CurrentDomain.GetAssemblies()
        '        Select New AssemblyName(e.FullName).Name

        'MsgBox(String.Join(vbCrLf, qr.ToArray()))

    End Sub

    Private Sub LoadModule(ByVal filepath As String)
        If Not String.IsNullOrEmpty(filepath) Then
            'Try
            Dim ass = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), filepath))
            Dim attr = ass.GetCustomAttributes(GetType(Common.EntryPointAttribute), False).FirstOrDefault()
            If attr IsNot Nothing Then

                'Try

                'Catch ex As Exception
                '    Dim o = ex
                '    Dim a = 1
                'End Try

                Dim servattr = ass.GetCustomAttributes(GetType(Common.DeclareServiceAttribute), False)
                If servattr IsNot Nothing Then
                    For Each e As Common.DeclareServiceAttribute In servattr
                        Dim infoattr = TryCast(e.InstanceType.GetCustomAttributes(GetType(Common.ServiceInfoAttribute), False).FirstOrDefault(), Common.ServiceInfoAttribute)
                        If infoattr IsNot Nothing Then
                            If infoattr.LifeTime = ServiceLifetime.Singleton Then
                                Dim inst = Activator.CreateInstance(e.InstanceType)
                                singleton.Add(e.InterfaceType, inst)
                                serviceTypes.Add(e.InterfaceType)
                                If Not String.IsNullOrEmpty(infoattr.Name) Then
                                    If Not String.IsNullOrWhiteSpace(infoattr.Name) Then
                                        serviceNames.Add(infoattr.Name.Trim(), e.InterfaceType)
                                    End If
                                End If
                                CType(inst, Common.IService).Initialize()
                            Else

                            End If
                        End If
                    Next
                End If


                Dim modtype As Type = CType(attr, Common.EntryPointAttribute).ModuleType
                Dim modul As IModule = Activator.CreateInstance(modtype)
                modules.Add(modul)
                modul.Load()
                modul.Reset(Me)
            End If
            'Catch ex As Exception
            '    MsgBox(ex.ToString)
            'End Try
        End If
    End Sub
    Public Overrides Function GetService(ByVal Name As String) As Object
        Return GetService(serviceNames(Name))
    End Function

    Public Overrides Function GetService(ByVal serviceType As System.Type) As Object
        If serviceTypes.Contains(serviceType) Then
            If singleton.ContainsKey(serviceType) Then
                Return singleton(serviceType)
            Else
                Dim result As IService = Activator.CreateInstance(serviceType)
                result.Initialize()
                Return result
            End If
        Else
            Throw New Exception("Service introuvable : " & serviceType.FullName)
        End If
    End Function

    Public Overrides ReadOnly Property LoadedModules As System.Collections.Generic.IEnumerable(Of System.Type)
        Get
            Return New ObjectModel.ReadOnlyCollection(Of Type)(modules)
        End Get
    End Property


    'Private DoingAsyncOp As Boolean = False
    'Public Overrides Sub StartAsyncOperation(ByVal ByV, ByVal Completed As System.Delegate, Optional ByVal ShowUI As Boolean = True)
    '    If Operation Is Nothing Or Completed Is Nothing Then Return
    '    If DoingAsyncOp And ShowUI Then Return

    '    Operation.BeginInvoke()

    'End Sub

    Public Overrides Sub StartAsyncOperation(ByVal Operation As Common.AsynchronousOperationHandler, ByVal info As Common.AsynchronousOperationInfo)
        If Operation Is Nothing Or info Is Nothing Then Return

        Dim ass = Assembly.GetCallingAssembly()

        Dim func = Function(m As IModule)
                       Return m.GetType()
                   End Function
        Dim q = From e In modules
                Where func(e).Assembly Is ass
                Select func(e)

        If q.Count <> 1 Then Return

        Operation.BeginInvoke(q.FirstOrDefault(), info.Data, AddressOf AsyncCallback, info)

        Me.GetService(Of IUIService)().ShowMessage( _
                info, _
                 Resizable:=False, _
                  ShowCloseButton:=False)

    End Sub

    Private Sub AsyncCallback(ByVal ar As System.IAsyncResult)
        MessageWindow.ForceClose = True
    End Sub

    Friend Shared Sub WpfAppCurrentExit(ByVal sender As Object, ByVal e As ExitEventArgs)
        For Each m In Instance.modules
            m.Unload()
        Next
    End Sub



End Class
